package TAProgram;

import basicBlock.BasicBlock;
import runTime.BlockToCode;


import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;

public class IR {
    public static BasicBlock startBlock;
    public static String IRCodes;

    public static TACode start;
    public static ArrayList<TACode> taCodes = new ArrayList<>();
    public static ArrayList<BasicBlock> basicBlocks = new ArrayList<>();

    public static HashMap<BasicBlock, Boolean> use = new HashMap<BasicBlock, Boolean>();
    public static HashMap<BasicBlock, Boolean> vis = new HashMap<BasicBlock, Boolean>();

    public static IR mock(){
        IR ir = new IR();
        //bb1
        TACode taCode1 = TACode.createTACode(
                //i = 1
                new OperatorType("+"),
                new Variable(null,false,ValueType.INTTYPE,2),
                new Variable(null,false,ValueType.INTTYPE,3),
                new Variable("i",false),
                null
        );
        //bb2
        TACode taCode2 = TACode.createTACode(
                //j = 1
                new OperatorType("+"),
                new Variable(null,false,ValueType.INTTYPE,1),
                new Variable(null,false,ValueType.INTTYPE,0),
                new Variable("j",false),
                null
        );
        //bb3
        TACode taCode3 =  TACode.createTACode(
                //t1 = 10 * i
                new OperatorType("*"),
                new Variable(null,false,ValueType.INTTYPE,8),
                new Variable("i",false),
                new Variable("t1",true),
                null
        );
        TACode taCode4 =  TACode.createTACode(
                //t2 = t1 + j
                new OperatorType("+"),
                new Variable("t1",true),
                new Variable("j",false),
                new Variable("t2",true),
                null
        );
        TACode taCode5 =  TACode.createTACode(
                //t2 = t2 * 8
                new OperatorType("+"),
                new Variable("t2",true),
                new Variable(null,false,ValueType.INTTYPE,0),
                new Variable("t2",true),
                null
        );
        TACode taCode6 =  TACode.createTACode(
                //j = a + b
                new OperatorType("+"),
                new Variable("a",true),
                new Variable("b",true),
                new Variable("j",true),
                null
        );
        TACode taCode7 =  TACode.createTACode(
                //t3 = a + b    ->  t3 = j
                new OperatorType("+"),
                new Variable("a",true),
                new Variable("b",true),
                new Variable("t3",true),
                null
        );
        //bb4
        TACode taCode8 =  TACode.createTACode(
                //j = j + 1
                new OperatorType("+"),
                new Variable("j",true),
                new Variable(null,false,ValueType.INTTYPE,88),
                new Variable("j",true),
                null
        );
        BasicBlock block1 = new BasicBlock(
                "BB1",
                taCode1,
                null
        );
        BasicBlock block2 = new BasicBlock(
                "BB2",
                taCode2,
                null
        );
        BasicBlock block3 = new BasicBlock(
                "BB3",
                taCode3,
                new ArrayList<TACode>(Arrays.asList(taCode4,taCode5,taCode6,taCode7))
        );
        BasicBlock block4 = new BasicBlock(
                "BB4",
                taCode8,
                null
        );
        block1.link(block2);
        block2.link(block3);
        block3.link(block4);
//        block2.link(block4);
        ir.startBlock = block1;
        IR.taCodes.addAll(Arrays.asList(taCode1,taCode2,taCode3,taCode4,taCode5,taCode6,taCode7,taCode8));
        IR.basicBlocks.add(block1);
        IR.basicBlocks.addAll(Arrays.asList(block2,block3,block4));
        return ir;
    }

    private static String getIR(BasicBlock start){
        String IRCodes = "";
        IRCodes += start.toString();
        var block = start;
        ArrayList<BasicBlock> nextBlocks = null;
        while(block != null && (nextBlocks = block.getNextBlocks()) != null && !nextBlocks.isEmpty()){
            for(var item : nextBlocks) {
                if(IR.vis.get(item) == null){
                    IR.vis.put(item,true);
                    IRCodes += item.toString();
                }
            }
            //bug 是图的话 有多条边如何解决
            //要按照顺序来给定的基本块
            block = nextBlocks.get(0);
        }
        return IRCodes;
    }

    @Override
    public String toString() {
//        return getIR(this.startBlock);
        return BlockToCode.genCode();
    }
}
